package com.linsir.config;

import com.alibaba.druid.pool.DruidDataSource;
import com.baomidou.mybatisplus.core.config.GlobalConfig;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Repository;

import javax.sql.DataSource;
import java.sql.SQLException;


/**
 * @ProjectName:linsir
 * @Package:com.linsir.config
 * @Title: LinDataSourceConfig
 * @Description: TODO
 * @Create:2021/5/26 23:54 by @author:Linsir
 * @Update:2021/5/26 23:54 by @author:Linsir
 * @UpdateRemark: 初始创建
 * @Version 1.0.0
 */
@Configuration
@MapperScan(basePackages = LinDataSourceConfig.BASEPACKAGE,sqlSessionFactoryRef = "linSqlSessionFactory",annotationClass = Repository.class,markerInterface = BaseMapper.class)
public class LinDataSourceConfig {

    static final String BASEPACKAGE="com.linsir.lin.mapper";
    static final String TYPEALIASESPACKAGE="com.linsir.lin.pojo";
    //static final String MAPPER_LOCATION = "classpath:linMapper/*.xml";



    @Value("${lin.datasource.url}")
    private String url;

    @Value("${lin.datasource.username}")
    private String username;

    @Value("${lin.datasource.password}")
    private String password;

    @Value("${lin.datasource.driverClassName}")
    private String driverClass;

    @Value("${spring.datasource.initialSize}")
    private int initialSize;

    @Value("${spring.datasource.minIdle}")
    private int minIdle;

    @Value("${spring.datasource.maxActive}")
    private int maxActive;

    @Value("${spring.datasource.maxWait}")
    private int maxWait;

    @Value("${spring.datasource.timeBetweenEvictionRunsMillis}")
    private int timeBetweenEvictionRunsMillis;

    @Value("${spring.datasource.minEvictableIdleTimeMillis}")
    private int minEvictableIdleTimeMillis;

    @Value("${spring.datasource.validationQuery}")
    private String validationQuery;

    @Value("${spring.datasource.testWhileIdle}")
    private boolean testWhileIdle;

    @Value("${spring.datasource.testOnBorrow}")
    private boolean testOnBorrow;

    @Value("${spring.datasource.testOnReturn}")
    private boolean testOnReturn;

    @Value("${spring.datasource.poolPreparedStatements}")
    private boolean poolPreparedStatements;

    @Value("${spring.datasource.maxPoolPreparedStatementPerConnectionSize}")
    private int maxPoolPreparedStatementPerConnectionSize;

    @Value("${spring.datasource.filters}")
    private String filters;

    @Value("{spring.datasource.connectionProperties}")
    private String connectionProperties;

    @Bean(name = "linDataSource")
    public DataSource linDataSource()
    {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setUrl(url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        dataSource.setDriverClassName(driverClass);

        //具体配置
        dataSource.setInitialSize(initialSize);
        dataSource.setMinIdle(minIdle);
        dataSource.setMaxActive(maxActive);
        dataSource.setMaxWait(maxWait);
        dataSource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
        dataSource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
        dataSource.setValidationQuery(validationQuery);
        dataSource.setTestWhileIdle(testWhileIdle);
        dataSource.setTestOnBorrow(testOnBorrow);
        dataSource.setTestOnReturn(testOnReturn);


        try {
            dataSource.setFilters("stat,wall,slf4j");
        } catch (SQLException e) {
            e.printStackTrace();
        }
        dataSource.setPoolPreparedStatements(poolPreparedStatements);
        dataSource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);
        try {
            dataSource.setFilters(filters);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        dataSource.setConnectionProperties(connectionProperties);
        return dataSource;

    }


    @Bean(name = "linTransactionManager")
    public DataSourceTransactionManager linTransactionManager() {
        return new DataSourceTransactionManager(linDataSource());
    }

    @Bean(name = "linSqlSessionFactory")
    public SqlSessionFactory linSqlSessionFactory(@Qualifier("linDataSource") DataSource dataSource,
                                                  @Qualifier("linglobalConfig") GlobalConfig globalConfig,
                                                  @Qualifier("linMybatisPlusInterceptor")MybatisPlusInterceptor mybatisPlusInterceptor) throws Exception {
            final MybatisSqlSessionFactoryBean sqlSessionFactoryBean = new MybatisSqlSessionFactoryBean();
            sqlSessionFactoryBean.setDataSource(dataSource);
            //sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(LinDataSourceConfig.MAPPER_LOCATION));
            sqlSessionFactoryBean.setTypeAliasesPackage(TYPEALIASESPACKAGE);
            sqlSessionFactoryBean.setGlobalConfig(globalConfig);
            sqlSessionFactoryBean.setPlugins(mybatisPlusInterceptor);
            return  sqlSessionFactoryBean.getObject();
        //     //分页插件
//     Interceptor interceptor = new PageInterceptor();
//     Properties properties = new Properties();
//     //数据库
//     properties.setProperty("helperDialect", "mysql");
//     //是否将参数offset作为PageNum使用
//     properties.setProperty("offsetAsPageNum", "true");
//     //是否进行count查询
//     properties.setProperty("rowBoundsWithCount", "true");
//     //是否分页合理化
//     properties.setProperty("reasonable", "false");
//     interceptor.setProperties(properties);
//     sessionFactory.setPlugins(new Interceptor[] {interceptor});


    }

    @Bean(name = "linSqlSessionTemplate")
    public SqlSessionTemplate linSqlSessionTemplate(@Qualifier("linSqlSessionFactory") SqlSessionFactory sessionFactory)
    {
        SqlSessionTemplate sqlSessionTemplate =new SqlSessionTemplate(sessionFactory);
        return  sqlSessionTemplate;
    }



    /*@Bean(name = "linMapperScannerConfigurer")
    public MapperScannerConfigurer  linMapperScannerConfigurer(@Qualifier("linSqlSessionTemplate") SqlSessionTemplate sqlSessionTemplate)
    {
        MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
        mapperScannerConfigurer.setBasePackage(LinDataSourceConfig.BASEPACKAGE);
        mapperScannerConfigurer.setSqlSessionTemplateBeanName("linSqlSessionTemplate");
        mapperScannerConfigurer.setSqlSessionFactoryBeanName("linSqlSessionFactory");
        return mapperScannerConfigurer;
    }*/

}
